package com.zdp.nio.channel.udpchannel.data;

import lombok.Builder;
import lombok.Data;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.Set;

/**
 * UDP服务端，利用 selector来监听连接事件
 */
@Data
@Builder
public class UDPServer {

    private boolean run = true;
    private String ip;
    private Integer port;

    public void receive() throws IOException {
        // 1. 创建 DatagramChannel对象
        DatagramChannel channel = DatagramChannel.open();
        // 1.1 设置非阻塞模式
        channel.configureBlocking(false);
        // 1.2 绑定地址
        channel.bind(new InetSocketAddress(ip, port));
        // 2. 创建 Selector对象
        Selector selector = Selector.open();
        // 3. 将 channel 注册到 selector
        channel.register(selector, SelectionKey.OP_READ);
        // 4. 通过 Selector监听事件 ( select()是阻塞的，直到监听到事件）
        while (selector.select() > 0) {
            // 4.1 获取到准备就绪的事件
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();

            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            while (iterator.hasNext()) {
                SelectionKey next = iterator.next();
                // 4.2 读取通道中的数据，读取到Buffer中
                if (next.isReadable()) {
                    SocketAddress receive = channel.receive(byteBuffer);
                    byteBuffer.flip();
                    String msg = new String(byteBuffer.array(), 0, byteBuffer.limit());
                    System.out.println(msg);
                    byteBuffer.clear();
                }
                iterator.remove();
            }
        }
        // 5. 关闭通道 和 选择器
        channel.close();
        selector.close();
    }

    public void stop() {
        this.run = false;
    }
}
